package com.gubatian.dfs.namenode.server;

import java.util.LinkedList;
import java.util.List;

/**
 * 负责管理内存中的文件目录树的核心组件
 *
 * @author: gubatian
 * @create: 2021-09-22 18:38
 */
public class FSDirectory {

    /**
     * 文件中的文件目录树
     */
    private INodeDirectory dirTree;
    public FSDirectory() {
        this.dirTree = new INodeDirectory();
    }
    /**
     * 创建目录
     * @param path 目录路径
     */
    public void mkdir(String path) {

        // path = /usr/warehouse/hive
        // 先判断一下“/”根目录下有没有usr目录
        // 如果有继续判断是否有warehouse这个目录，如果没有
        // 先创建一个warehouse对应的目录挂在usr目录下
        // 再创建一个hive目录挂在warehouse目录下

        synchronized (dirTree) {
            String[] splitPaths = path.split("/");
            // 定义父级目录
            INodeDirectory parent = null;
            for (String splitPath : splitPaths) {
                // 根目录不做创建
                if (splitPath.trim().equals("")) {
                    continue;
                }
                INodeDirectory dir = findDirectory(dirTree, path);
                if (dir != null) {
                    parent = dir;
                    continue;
                }

                INodeDirectory child = new INodeDirectory();
                parent.addChild(child);
            }
        }
    }

    /**
     * 对文件目录树递归查找目录
     * @param dir
     * @param path
     * @return
     */
    private INodeDirectory findDirectory(INodeDirectory dir, String path) {
        // 该文件目录树没有子目录，直接返回null
        if (dir.getChildren().size() == 0) {
            return null;
        }
        INodeDirectory resultDir;
        for(INode child : dir.getChildren()) {
            if (child instanceof INodeDirectory) {
                INodeDirectory childDir = (INodeDirectory) child;
                if (childDir.getPath().equals(path)) {
                    return childDir;
                }
                // 继续向子目录的下级目录寻找
                resultDir = findDirectory(childDir, path);
                if (resultDir != null) {
                    return resultDir;
                }
            }

        }
        return null;
    }

    /**
     * 代表的是文件目录树中的一个节点
     */
    private interface INode {

    }

    public static class INodeDirectory implements INode {
        private String path;
        private List<INode> children;

        public INodeDirectory() {
            children = new LinkedList<>();
        }

        public void addChild(INode iNode) {
            this.children.add(iNode);
        }
        public String getPath() {
            return path;
        }
        public void setPath(String path) {
            this.path = path;
        }
        public List<INode> getChildren() {
            return children;
        }
        public void setChildren(List<INode> children) {
            this.children = children;
        }
    }

    /**
     * 代表文件目录树中的一个文件
     */
    public static class INodeFile implements INode {
        private String name;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
}